home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi Magazine Collection 2001
/
Delphi Magazine Collection 20001 (2001).iso
/
DISKS
/
ISSUE23
/
PASTOWEB
/
Convert.pas
next >
Wrap
Pascal/Delphi Source File
|
1997-05-20
|
15KB
|
548 lines
unit Convert;
interface
uses
Classes, NewParse;
type
KeywordType = (ktPascal, ktDfm);
TCodeParser = class (TNewParser)
public
constructor Create (SSource, SDest: TStream);
procedure SetKeywordType (Kt: KeywordType);
// conversion
procedure Convert;
protected
// virtual methods (mostly virtual abstract)
procedure BeforeString; virtual; abstract;
procedure AfterString; virtual; abstract;
procedure BeforeKeyword; virtual; abstract;
procedure AfterKeyword; virtual; abstract;
procedure BeforeComment; virtual; abstract;
procedure AfterComment; virtual; abstract;
procedure InitFile; virtual; abstract;
procedure EndFile; virtual; abstract;
function CheckSpecialToken (Ch1: char): string; virtual;
function MakeStringLegal (S: String): string; virtual;
function MakeCommentLegal (S: String): string; virtual;
protected
Source, Dest: TStream;
OutStr: string;
FKeywords: TStrings;
Line, Pos: Integer;
end;
THtmlParser = class (TCodeParser)
public
FileName: string;
Copyright: string;
Alone: Boolean;
procedure AddFileHeader (FileName: string);
class function HtmlHead (Filename: string): string;
class function HtmlTail (Copyright: string): string;
protected
// virtual methods
procedure BeforeString; override;
procedure AfterString; override;
procedure BeforeKeyword; override;
procedure AfterKeyword; override;
procedure BeforeComment; override;
procedure AfterComment; override;
procedure InitFile; override;
procedure EndFile; override;
function CheckSpecialToken (Ch1: char): string; override;
end;
// functions to be used by a Wizard
function OpenProjectToHTML (Filename, Copyright: string): string;
function CurrProjectToHTML (Copyright: string): string;
implementation
uses
ExptIntf, SysUtils, ToolIntf;
var
PascalKeywords: TStrings;
DfmKeywords: TStrings;
const
Quote = '''';
//////////// class TCodeParser ////////////
constructor TCodeParser.Create (SSource, SDest: TStream);
begin
inherited Create (SSource);
Source := SSource;
Dest := SDest;
SetLength (OutStr, 10000);
OutStr := '';
FKeywords := PascalKeywords;
end;
procedure TCodeParser.SetKeywordType (Kt: KeywordType);
begin
case Kt of
ktPascal: FKeywords := PascalKeywords;
ktDfm: FKeywords := DfmKeywords;
else
raise Exception.Create ('Undefined keywords type');
end;
end;
procedure TCodeParser.Convert;
begin
InitFile; // virtual
Line := 1;
Pos := 0;
// parse the entire source file
while Token <> toEOF do
begin
// if the source code line has changed,
// add the proper newline character
while SourceLine > Line do
begin
AppendStr (OutStr, #13#10);
Inc (Line);
Pos := Pos + 2; // 2 characters, cr+lf
end;
// add proper white spaces (formatting)
while SourcePos > Pos do
begin
AppendStr (OutStr, ' ');
Inc (Pos);
end;
// check the token
case Token of
toSymbol:
begin
// if the token is not a keyword
if FKeywords.IndexOf (TokenString) < 0 then
// add the plain token
AppendStr (OutStr, TokenString)
else
begin
BeforeKeyword; // virtual
AppendStr (OutStr, TokenString);
AfterKeyword; // virtual
end;
end;
toString:
begin
BeforeString; // virtual
if (Length (TokenString) = 1) and
(Ord (TokenString [1]) < 32) then
begin
AppendStr (OutStr, '#' +
IntToStr (Ord (TokenString [1])));
if Ord (TokenString [1]) < 10 then
Pos := Pos + 1
else
Pos := Pos + 2;
end
else
begin
AppendStr (OutStr, MakeStringLegal (TokenString));
Pos := Pos + 2; // 2 x hypen
end;
AfterString; // virtual
end;
toInteger:
AppendStr (OutStr, TokenString);
toFloat:
AppendStr (OutStr, TokenString);
toComment:
begin
BeforeComment; // virtual
AppendStr (OutStr, MakeCommentLegal (TokenString));
AfterComment; // virtual
end;
else
// any other token
AppendStr (OutStr, CheckSpecialToken (Token));
end; // case Token of
// increase the current position
Pos := Pos + Length (TokenString);
// move to the next token
NextToken;
end; // while Token <> toEOF do
// add final code
EndFile; // virtual
// add the string to the stream
Dest.WriteBuffer (Pointer(OutStr)^, Length (OutStr));
end;
function TCodeParser.CheckSpecialToken (Ch1: char): string;
begin
Result := Ch1; // do nothing
end;
function TCodeParser.MakeStringLegal (S: String): string;
var
I: Integer;
begin
if Length (S) < 1 then
begin
Result := Quote + Quote;
Exit;
end;
// if the first character is not special,
// add the open quote
if S[1] > #31 then
Result := Quote
else
Result := '';
// for each character of the string
for I := 1 to Length (S) do
case S [I] of
// quotes must be doubled
Quote: begin
AppendStr (Result, Quote + Quote);
Pos := Pos + 1;
end;
// special characters (characters below the value 32)
#0..#31: begin
Pos := Pos + Length (IntToStr (Ord (S[I])));
// if preceeding characters are plain ones,
// close the string
if (I > 1) and (S[I-1] > #31) then
AppendStr (Result, Quote);
// add the special character
AppendStr (Result, '#' + IntToStr (Ord (S[I])));
// if the following characters are plain ones,
// open the string
if (I < Length (S) - 1) and (S[I+1] > #31) then
AppendStr (Result, Quote);
end;
else
AppendStr (Result, CheckSpecialToken(S[I]));
end;
// if the last character was not special,
// add closing quote
if (S[Length (S)] > #31) then
AppendStr (Result, Quote);
end;
function TCodeParser.MakeCommentLegal (S: String): string;
var
I: Integer;
begin
Result := '';
// for each character of the string
for I := 1 to Length (S) do
AppendStr (Result, CheckSpecialToken(S[I]));
end;
//////////// class THtmlParser ////////////
procedure THtmlParser.InitFile;
begin
if Alone then
AppendStr (OutStr, HtmlHead (Filename));
AddFileHeader (Filename);
AppendStr (OutStr, '<PRE>'#13#10);
end;
procedure THtmlParser.EndFile;
begin
AppendStr (OutStr, '</PRE>');
if Alone then
AppendStr (OutStr, HtmlTail (Copyright))
else
AppendStr (OutStr, #13#10'<HR>'#13#10#13#10); // separator
end;
procedure THtmlParser.BeforeComment;
begin
AppendStr (OutStr, '<FONT COLOR="#000080"><I>');
end;
procedure THtmlParser.AfterComment;
begin
AppendStr (OutStr, '</I></FONT>');
end;
procedure THtmlParser.BeforeKeyword;
begin
AppendStr (OutStr, '<B>');
end;
procedure THtmlParser.AfterKeyword;
begin
AppendStr (OutStr, '</B>');
end;
procedure THtmlParser.BeforeString;
begin
// no special style...
end;
procedure THtmlParser.AfterString;
begin
// no special style...
end;
function THtmlParser.CheckSpecialToken (Ch1: char): string;
begin
case Ch1 of
'<': Result := '<';
'>': Result := '>';
'&': Result := '&';
'"': Result := '"';
else
Result := Ch1;
end;
end;
procedure THtmlParser.AddFileHeader (FileName: string);
var
FName: string;
begin
FName := Uppercase (ExtractFilename (FileName));
AppendStr (OutStr, Format (
'<A NAME=%s><H3>%s</H3></A>' + #13#10 + #13#10,
[FName, FName]));
end;
class function THtmlParser.HtmlHead (Filename: string): string;
begin
Result := '<HTML><HEAD>' + #13#10 +
'<TITLE>File: ' + ExtractFileName(Filename) + '</TITLE>' + #13#10 +
'<META NAME="GENERATOR" CONTENT="PasToWeb[Marco Cant∙]">'#13#10 +
'</HEAD>'#13#10 +
'<BODY BGCOLOR="#FFFFFF">'#13#10;
end;
class function THtmlParser.HtmlTail (Copyright: string): string;
begin
Result := '<HR><CENTER<I>Generated by PasToWeb,' +
' a tool by Marco Cantù.<P>' + #13#10 +
Copyright + '</CENTER></I>'#13#10 + '</BODY> </HTML>';
end;
// code for the wizard...
function OpenProjectToHTML (Filename, Copyright: string): string;
begin
// open the project and get the lists...
ToolServices.OpenProject (FileName);
Result := CurrProjectToHTML (Copyright);
end;
function CurrProjectToHTML (Copyright: string): string;
var
Dest, Source, BinSource: TStream;
HTML, FileName, Ext, FName: string;
I: Integer;
Parser: THtmlParser;
begin
// initialize
FileName := ToolServices.GetProjectName;
Result := ChangeFileExt (FileName, '_dpr') + '.htm';
Dest := TFileStream.Create (Result,
fmCreate or fmOpenWrite);
try
// add head
HTML := '<HTML><HEAD>' + #13#10 +
'<TITLE>Project: ' + ExtractFileName (Filename) +
'</TITLE>' + #13#10 +
'<META NAME="GENERATOR" CONTENT="PasToHTML[Marco Cant∙]">' + #13#10 +
'</HEAD>'#13#10 +
'<BODY BGCOLOR="#FFFFFF">'#13#10 +
'<H1><CENTER>Project: ' + FileName +
'</CENTER></H1><BR><BR><HR>'#13#10;
AppendStr (HTML, '<UL>'#13#10);
// units list
for I := 0 to ToolServices.GetUnitCount - 1 do
begin
Ext := Uppercase (ExtractFileExt(
ToolServices.GetUnitName(I)));
FName := Uppercase (ExtractFilename (
ToolServices.GetUnitName(I)));
if (Ext <> '.RES') and (Ext <> '.DOF') then
AppendStr (HTML, '<LI> <A HREF=#' + FName + '> ' +
FName + '</A>'#13#10);
end;
// forms list
for I := 0 to ToolServices.GetFormCount - 1 do
begin
FName := Uppercase (ExtractFilename (
ToolServices.GetFormName(I)));
AppendStr (HTML, '<LI> <A HREF=#' + FName + '> ' +
FName + '</A>'#13#10);
end;
AppendStr (HTML, '</UL>'#13#10);
AppendStr (HTML, '<HR>'#13#10);
// add the HTML string to the output buffer
Dest.WriteBuffer (Pointer(HTML)^, Length (HTML));
// generate the HTML code for the units
for I := 0 to ToolServices.GetUnitCount - 1 do
begin
Ext := Uppercase (ExtractFileExt(
ToolServices.GetUnitName(I)));
if (Ext <> '.RES') and (Ext <> '.DOF') then
begin
Source := TFileStream.Create (
ToolServices.GetUnitName(I), fmOpenRead);
Parser := THtmlParser.Create (Source, Dest);
try
Parser.Alone := False;
Parser.Filename := ToolServices.GetUnitName(I);
Parser.Convert;
finally
Parser.Free;
Source.Free;
end;
end; // if
end; // for
// generate the HTML code for forms
for I := 0 to ToolServices.GetFormCount - 1 do
begin
// convert the DFM file to text
BinSource := TFileStream.Create (
ToolServices.GetFormName(I), fmOpenRead);
Source := TMemoryStream.Create;
ObjectResourceToText (BinSource, Source);
Source.Position := 0;
Parser := THtmlParser.Create (Source, Dest);
try
Parser.Alone := False;
Parser.Filename := ToolServices.GetFormName(I);
Parser.SetKeywordType (ktDfm);
Parser.Convert;
finally
Parser.Free;
BinSource.Free;
Source.Free;
end;
end; // for
// add the tail of the HTML file
HTML :=
'<BR><I><CENTER>HTML file generated by PasToWeb, a tool by Marco Cantù<BR>'#13#10 +
Copyright + '</CENTER></I>'#13#10 +
'</BODY> </HTML>';
Dest.WriteBuffer (Pointer(HTML)^, Length (HTML));
finally
Dest.Free;
end;
end;
initialization
PascalKeywords := TStringList.Create;
DfmKeywords := TStringList.Create;
// Pascal Keywords
PascalKeywords.Add ('absolute');
PascalKeywords.Add ('abstract');
PascalKeywords.Add ('and');
PascalKeywords.Add ('array');
PascalKeywords.Add ('as');
PascalKeywords.Add ('asm');
PascalKeywords.Add ('assembler');
PascalKeywords.Add ('at');
PascalKeywords.Add ('automated');
PascalKeywords.Add ('begin');
PascalKeywords.Add ('case');
PascalKeywords.Add ('cdecl');
PascalKeywords.Add ('class');
PascalKeywords.Add ('const');
PascalKeywords.Add ('constructor');
PascalKeywords.Add ('contains');
PascalKeywords.Add ('default');
PascalKeywords.Add ('destructor');
PascalKeywords.Add ('dispid');
PascalKeywords.Add ('dispinterface');
PascalKeywords.Add ('div');
PascalKeywords.Add ('do');
PascalKeywords.Add ('downto');
PascalKeywords.Add ('dynamic');
PascalKeywords.Add ('else');
PascalKeywords.Add ('end');
PascalKeywords.Add ('except');
PascalKeywords.Add ('exports');
PascalKeywords.Add ('external');
PascalKeywords.Add ('file');
PascalKeywords.Add ('finalization');
PascalKeywords.Add ('finally');
PascalKeywords.Add ('for');
PascalKeywords.Add ('forward');
PascalKeywords.Add ('function');
PascalKeywords.Add ('goto');
PascalKeywords.Add ('if');
PascalKeywords.Add ('implementation');
PascalKeywords.Add ('in');
PascalKeywords.Add ('index');
PascalKeywords.Add ('inherited');
PascalKeywords.Add ('initialization');
PascalKeywords.Add ('inline');
PascalKeywords.Add ('interface');
PascalKeywords.Add ('is');
PascalKeywords.Add ('label');
PascalKeywords.Add ('library');
PascalKeywords.Add ('message');
PascalKeywords.Add ('mod');
// PascalKeywords.Add ('name');
PascalKeywords.Add ('nil');
PascalKeywords.Add ('nodefault');
PascalKeywords.Add ('not');
PascalKeywords.Add ('object');
PascalKeywords.Add ('of');
PascalKeywords.Add ('on');
PascalKeywords.Add ('or');
PascalKeywords.Add ('override');
PascalKeywords.Add ('packed');
PascalKeywords.Add ('pascal');
PascalKeywords.Add ('private');
PascalKeywords.Add ('procedure');
PascalKeywords.Add ('program');
PascalKeywords.Add ('property');
PascalKeywords.Add ('protected');
PascalKeywords.Add ('public');
PascalKeywords.Add ('published');
PascalKeywords.Add ('raise');
PascalKeywords.Add ('read');
PascalKeywords.Add ('record');
PascalKeywords.Add ('register');
PascalKeywords.Add ('repeat');
PascalKeywords.Add ('requires');
PascalKeywords.Add ('resident');
PascalKeywords.Add ('set');
PascalKeywords.Add ('shl');
PascalKeywords.Add ('shr');
PascalKeywords.Add ('stdcall');
PascalKeywords.Add ('stored');
PascalKeywords.Add ('string');
PascalKeywords.Add ('then');
PascalKeywords.Add ('threadvar');
PascalKeywords.Add ('to');
PascalKeywords.Add ('try');
PascalKeywords.Add ('type');
PascalKeywords.Add ('unit');
PascalKeywords.Add ('until');
PascalKeywords.Add ('uses');
PascalKeywords.Add ('var');
PascalKeywords.Add ('virtual');
PascalKeywords.Add ('while');
PascalKeywords.Add ('with');
PascalKeywords.Add ('write');
PascalKeywords.Add ('xor');
// DFm keywords
DfmKeywords.Add ('object');
DfmKeywords.Add ('end');
finalization
PascalKeywords.Free;
end.